home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / p_misc / 7p203upp.exe / V203SRC.LZH / ENCODE.C < prev    next >
C/C++ Source or Header  |  1992-07-17  |  18KB  |  633 lines

  1. #include "7plus.h"
  2. #include "globals.h"
  3.  
  4. /*
  5. *** encode a file. split, if desired/needed. create correction file.
  6. ***
  7. ***
  8.  */
  9.  
  10. int encode_file (char *name, long blocksize, char *searchbin,
  11.                                                    int _part, char *head_foot)
  12. {
  13.   int      part, parts, blocklines, curline;
  14.   int      correct, corrlines , corrpart, corrline, tune;
  15.   uint     csequence;
  16.   ulong    ftimestamp, ftstamp0 , after[16], *af, h;
  17.   long     binbytes, binb0, position, size, corrsize;
  18.   char     destname[13], hdrname[MAXFNAME], filename[13], corrname[13];
  19.   char     orgname[66], inpath[MAXFPATH], line[81], line2[81];
  20.   char     dummi[20], dummi2[20], *q, *r;
  21.   char     go_buf[257], stop_buf[257], cor_head[129];
  22.  
  23.   FILE     *in, *out, *corr;
  24.   register i, j, k;
  25.  
  26.   correct = i = corrpart = corrlines  = blocklines = 0;
  27.   *destname = *hdrname = *filename = *corrname = *inpath = *orgname = EOS;
  28.   *_file = *go_buf = *stop_buf = EOS;
  29.   in = out = corr = NULLFP;
  30.   ftimestamp = ftstamp0 = 0UL;
  31.   corrsize = 0L;
  32.  
  33.   #ifdef TWO_CHAR_SEP
  34.    tune = 1;
  35.   #else
  36.    tune = 0;
  37.   #endif
  38.  
  39.   if (fls)
  40.     if (!test_exist ("7plus.fls"))
  41.       unlink ("7plus.fls");
  42.  
  43.   if (searchbin)
  44.   {
  45.     /* Get serchpath for binary (original) file. */
  46.     fnsplit (searchbin, _drive, _dir, _file, _ext);
  47.     sprintf (inpath, "%s%s", _drive, _dir);
  48.   }
  49.  
  50.   q = name;
  51.   /* create correction file, if ext of input file is .ERR */
  52.   if ((r = strrchr (q, '.')) != NULL)
  53.     if (!strnicmp (".err", r, 4))
  54.     {
  55.       /* OK, input file is an error file */
  56.       correct = 1;
  57.  
  58.       if ((i = crc_file (q, "7PLUS error", "00\n", 1)) != 0)
  59.         if (i != 17)
  60.           return (i);
  61.  
  62.       corr = fopen (q, OPEN_READ_TEXT);
  63.  
  64.       /* Find starting line. */
  65.       while ((r = my_fgets (line, 80, corr)) != NULL)
  66.         if (!strncmp (line, "7PLUS ", 6))
  67.           break;
  68.  
  69.       if (!r)
  70.       {
  71.         printf ("\007'%s': invalid error report. Break.\n", q);
  72.         fclose (corr);
  73.         return (7);
  74.       }
  75.       /* Get name, lines per part, and length of original
  76.          file from error file.*/
  77.       *orgname = EOS;
  78.       binb0 = 0L;
  79.       ftstamp0 = 0UL;
  80.       sscanf (line+20, "%12s %s /%66[^/]/ %ld",
  81.                           corrname, dummi, orgname, &binb0);
  82.       corrlines  = get_hex (dummi);
  83.       if (!*orgname)
  84.       {
  85.         binb0 = 0L;
  86.         sscanf (line+20, "%s %s %ld",
  87.                                       dummi, dummi, &binb0);
  88.       }
  89.       strlwr (corrname);
  90.       if (extended != '*' || !*orgname)
  91.         strcpy (orgname, corrname);
  92.       /* Build complete filename for original file */
  93.       if (!*_file)
  94.         strcat (inpath, orgname);
  95.       else
  96.       {
  97.         strcat (inpath, _file);
  98.         strcat (inpath, _ext);
  99.       }
  100.       q = inpath;
  101.     }
  102.  
  103.   if (!(in = fopen (q, OPEN_READ_BINARY)))
  104.   {
  105.     printf ("\007'%s' not found. Break.\n", q);
  106.     return (2);
  107.   }
  108.  
  109.   if (head_foot && !correct)
  110.     read_tb (head_foot, go_buf, stop_buf);
  111.  
  112.   /* Get file's timestamp */
  113.   #if defined (__MSDOS__) || (__TOS__)
  114.    ftimestamp = get_filetime (in);
  115.   #else
  116.    ftimestamp = get_filetime (q);
  117.   #endif
  118.  
  119.   /* determine size of original file. This could be done with filestat(),
  120.      but it's not available on all compilers. */
  121.   fseek (in, 0L, SEEK_END); /* position read pointer to end of file. */
  122.   size = ftell (in);        /* get size. */
  123.   fseek (in, 0L, SEEK_SET); /* reposition to beginning of file. */
  124.  
  125.   if (correct && binb0 && size != binb0)
  126.   {
  127.     printf (notsame, "error report");
  128.     fclose (in);
  129.     fclose (corr);
  130.     return (15);
  131.   }
  132.  
  133.   part = parts = 1;
  134.  
  135.   if (!correct)
  136.   {
  137.     /* Bufferize input, if we're encoding. */
  138.     setvbuf (in, NULL, _IOFBF, buflen);
  139.  
  140.     /* if blocksize is greater then try to split into blocksize-50000 parts */
  141.     if (blocksize > 50000L)
  142.     {
  143.       blocksize -= 50000L;
  144.       /* calculate how many ascii-bytes per part are needed to get roughly
  145.          equal filelengths. */
  146.       blocksize = (((size + 61) / 62) + (blocksize - 1)) / blocksize;
  147.       blocksize *= 62;
  148.     }
  149.  
  150.     /* if blocksize is defined as zero or if it's bigger than the file,
  151.        set it to filelength  */
  152.     if (!blocksize || blocksize > size)
  153.       blocksize = size;
  154.  
  155.     /* automatically split into 512 line parts, if file is bigger. */
  156.     if (blocksize > (512 * 62))
  157.     {
  158.       blocksize = 512 * 62;
  159.       printf ("Blocksize limited to 512 lines per file.\n");
  160.     }
  161.     /* how many lines do the parts contain? */
  162.     blocklines = (int) ((blocksize + 61) / 62);
  163.  
  164.     /* how many parts result from that? */
  165.     parts = (int) ((size + blocksize-1) / blocksize);
  166.  
  167.     if (parts > 255)
  168.     {
  169.       printf ("\007Not more than 255 parts allowed.\n");
  170.       printf ("Choose different blocksize. Break.\n");
  171.       fclose (in);
  172.       return (8);
  173.     }
  174.   }
  175.   else
  176.     if (blocksize > 50000L || blocksize == 138L*62L)
  177.       blocksize = 9940L;
  178.     else
  179.       blocksize = (blocksize/62) *71;
  180.  
  181.   /* generate filenames */
  182.   fnsplit (q, NULL, NULL, _file, _ext);
  183.   sprintf (orgname, "%s%s", _file, _ext);
  184.   build_DOS_name (_file);
  185.   build_DOS_name (_ext);
  186.   /* make sure, the name isn't longer than 8 chars
  187.      and extension not longer 4 (including dot). */
  188.   _file[8] = _ext[3] = EOS;
  189.  
  190.   strcpy (destname, _file);
  191.   sprintf (hdrname, "%s%s%s", _file, _ext[0]?".":"", _ext);
  192.   strupr (hdrname);
  193.  
  194.   if (!correct)
  195.     printf ("\n-----------\nEncoding...\n-----------\n\n");
  196.   else
  197.     printf ("\n---------------------------\nCreating correction file...\n\
  198. ---------------------------\n\n");
  199.  
  200.   if (!_part)
  201.     part = 1;
  202.   else
  203.   {
  204.     if (_part > parts || _part < 0)
  205.     {
  206.       printf ("\007Can't encode part %d of %d... You're pulling my leg!\n", _part, parts);
  207.       return (1);
  208.     }
  209.     part = _part;
  210.   }
  211.   /* encode parts */
  212.   for (; part<parts+1 ; part++)
  213.   {
  214.     if (!correct)
  215.     {
  216.       /* generate output filename. *.7PL, if unsplit. *.PXX if split.
  217.          XX represents a two digit hex number. */
  218.       if (parts == 1)
  219.       {
  220.         sprintf (filename, "%s%s", destname, ".7pl");
  221.         printf ("'%s': Writing.\r", filename);
  222.       }
  223.       else
  224.       {
  225.         sprintf (filename, "%s.p%02x", destname, part);
  226.         printf ("'%s': Writing part %03d of %03d.\r", filename, part, parts);
  227.       }
  228.  
  229.       fflush (stdout);
  230.  
  231.       /* check, if output file already exists. */
  232.       test_file (out, filename, 0, 12);
  233.     }
  234.     else /* we're creating a correction file, set name accordingly. */
  235.     {
  236.       fnsplit (corrname, NULL, NULL, destname, NULL);
  237.       sprintf (filename, "%s.cor", destname);
  238.     }
  239.     out = fopen (filename, OPEN_WRITE_TEXT);
  240.     setvbuf (out, NULL, _IOFBF, buflen);
  241.  
  242.     if (!correct)
  243.     {
  244.       if (part == parts && parts > 1)
  245.       {
  246.         if (size % blocksize)
  247.           blocksize = size % blocksize;
  248.         blocksize = ((blocksize + 61 ) / 62) *62;
  249.       }
  250.  
  251.       top_bottom (out, go_buf, hdrname, part, parts);
  252.  
  253.       /* output header */
  254.       sprintf (line, " go_7+. %03d of %03d %-12s %07ld %04X %03X (7PLUS v2.0) \
  255. \xb0\xb1\xb2%c", part, parts, hdrname, size,
  256.                     (uint)(((blocksize+61)/62) * 64), blocklines, extended);
  257.  
  258.       mcrc (line, 1);
  259.       add_crc2 (line);
  260.       fprintf (out, "%s%s", line, delimit);
  261.  
  262.       if (part == 1 && extended == '*')
  263.       {
  264.         sprintf (line, "///////////////////////////////////////////////////\
  265. ///////////\xb0\xb1\xb2*");
  266.         memcpy (line+1, orgname, strlen(orgname));
  267.         mcrc (line, 1);
  268.         add_crc2 (line);
  269.         fprintf (out, "%s%s", line, delimit);
  270.       }
  271.     }
  272.     else
  273.     {
  274.       /* output correction file header */
  275.       strcpy (dummi2, filename);
  276.       strupr (dummi2);
  277.       strupr (corrname);
  278.       sprintf (cor_head, " go_text. %s%s7PLUS correction: %s %ld %03X", dummi2, delimit, corrname, size, corrlines );
  279.       if (ftimestamp)
  280.       {
  281.         sprintf (dummi, " [%lX]", ftimestamp);
  282.         strcat (cor_head, dummi);
  283.       }
  284.       strcat (cor_head, delimit);
  285.       corrsize += fprintf (out, "%s", cor_head) +tune;
  286.  
  287.       strlwr (corrname);
  288.       fscanf (corr, "%s", dummi2);
  289.       corrpart = get_hex (dummi2);
  290.       corrsize += fprintf (out, " P%02x:%s", corrpart, delimit) +tune;
  291.  
  292.       printf ("Compiling: '%s'\r", filename);
  293.       fflush (stdout);
  294.     }
  295.  
  296.     curline = j = 0;
  297.     binbytes = 0L;
  298.  
  299.     if (_part)
  300.       fseek (in, (long) blocksize * (_part -1), SEEK_SET);
  301.  
  302.     /* get bytes from original file until it ends or blocksize is reached. */
  303.     while (!feof(in) && ((binbytes < blocksize) || parts == 1) || correct)
  304.     {
  305.       csequence = 0;
  306.  
  307.       if (correct)
  308.       {
  309.         /* get number of part and number of line to put into correction file
  310.            from error file */
  311.         fscanf (corr, "%s", dummi2);
  312.         corrline  = get_hex (dummi2);
  313.         if (corrline  == 0xfff || corrsize > blocksize)
  314.         {
  315.           if (corrline  == 0xfff)
  316.           {
  317.             corrpart = 0;
  318.             fscanf (corr, "%s", dummi2);
  319.             corrpart = get_hex (dummi2);
  320.             if (!corrpart)
  321.             {
  322.               sscanf (dummi2, "[%lX]", &ftstamp0);
  323.               corrsize = (long) blocksize+1;
  324.               printf ("\n");
  325.             }
  326.             else
  327.             {
  328.               fscanf (corr, "%s", dummi2);
  329.               corrline  = get_hex (dummi2);
  330.             }
  331.           }
  332.           if (corrsize > blocksize)
  333.           {
  334.             corrsize = 0L;
  335.  
  336.             /* if we were creating a correction file, complete it. */
  337.             fprintf (out, " P00:%s________%s stop_text.%s",
  338.                                                    delimit, delimit, delimit);
  339.             if (endstr)
  340.               fprintf (out, "%s%s", endstr, delimit);
  341.             fclose (out);
  342.  
  343.             crc_file (filename, "7P", " P00:\n", 0);
  344.  
  345.             if (!corrpart)
  346.               break;
  347.  
  348.             fnsplit (corrname, NULL, NULL, destname, NULL);
  349.             sprintf (filename, "%s.c%02x", destname, part++);
  350.  
  351.             out = fopen (filename, OPEN_WRITE_TEXT);
  352.             setvbuf (out, NULL, _IOFBF, buflen);
  353.  
  354.             corrsize += fprintf (out, "%s", cor_head) +tune;
  355.  
  356.             printf ("Compiling: '%s'\r", filename);
  357.             fflush (stdout);
  358.           }
  359.           corrsize += fprintf (out, " P%02X:%s", corrpart, delimit) +tune;
  360.         }
  361.         curline = corrline ;
  362.         /* calculate position in original file to get data from. */
  363.         position =  (long)(corrpart-1) * 62 * (long)corrlines  +
  364.                     62 * (long)corrline  ;
  365.         /* position read pointer. */
  366.         fseek (in, position, SEEK_SET);
  367.         corrsize += fprintf (out, " L%03X:%s", corrline , delimit) +tune;
  368.       }
  369.  
  370.       /* get two groups of 31 bytes and stuff them into 2 * 8 longs. */
  371.       af = after;
  372.       for (i=0; i<2; i++, af+=8)
  373.       {
  374.         /* Get 31 Bytes and put them into 8 longs. */
  375.         for(j=0; j<8; j++)
  376.         {
  377.           af[j] = 0L;
  378.           for (k=(j==7)?2:3; k>-1; k--)
  379.           {
  380.             if ((h = fgetc (in)) == EOF)
  381.             {
  382.               if (!i && !j && k == 3)
  383.                 i = 255;
  384.               h = 0L;
  385.             }
  386.             af[j] = (af[j] << 8) | h;
  387.           }
  388.         }
  389.         /* Rearrange into 8 31bit values. */
  390.         af[7] =  af[7]       | ((af[6] & 127L) << 24);
  391.         af[6] = (af[6] >> 7) | ((af[5] & 63L ) << 25);
  392.         af[5] = (af[5] >> 6) | ((af[4] & 31L ) << 26);
  393.         af[4] = (af[4] >> 5) | ((af[3] & 15L ) << 27);
  394.         af[3] = (af[3] >> 4) | ((af[2] & 7L  ) << 28);
  395.         af[2] = (af[2] >> 3) | ((af[1] & 3L  ) << 29);
  396.         af[1] = (af[1] >> 2) | ((af[0] & 1L  ) << 30);
  397.         af[0] = (af[0] >> 1);
  398.       }
  399.       /* i is 256, then no bytes were read. End of file. */
  400.       if (i == 256)
  401.         break;
  402.  
  403.       binbytes += 62;
  404.  
  405.       /* write code line to output file. do radix216 conversion, crc
  406.          calculation and ascii conversion as we go along. */
  407.       for (i=j=0;i<16;i++)
  408.       {
  409.         line2[j++]  = code[(int)(after[i] % 0xd8L)];
  410.         after[i]  /= 0xd8L;
  411.         line2[j++]  = code[(int)(after[i] % 0xd8L)];
  412.         after[i]  /= 0xd8L;
  413.         line2[j++]  = code[(int)(after[i] % 0xd8L)];
  414.         line2[j++]  = code[(int)(after[i] / 0xd8L)];
  415.       }
  416.  
  417.       for (i=0;i<64;i++)
  418.         csequence = crctab[csequence>>8] ^ (((csequence&255)<<8) |
  419.                                                          (byte) line2[i]);
  420.  
  421.       /* package line number and crc into three radix216 bytes and add
  422.          to code line. */
  423.       after[0]  = ((long)(curline & 0x1ff) << 14) | (csequence & 0x3fff);
  424.       line2[j++] = code[(int) (after[0] % 0xd8L)];
  425.       after[0] /= 0xd8L;
  426.       line2[j++] = code[(int) (after[0] % 0xd8L)];
  427.       line2[j++] = code[(int) (after[0] / 0xd8L)];
  428.  
  429.       add_crc2 (line2);
  430.       corrsize += fprintf (out, "%s", line2) +tune;
  431.  
  432.       /* conclude line with line separator. */
  433.       corrsize += fprintf (out, delimit);
  434.       curline++; /* increase line counter. */
  435.     }
  436.  
  437.     if (!correct) /* put end indicator into output file. */
  438.     {
  439.       strupr (filename);
  440.  
  441.       /* Add timestamp */
  442.       sprintf (line, "                                                  \
  443.             \xb0\xb1\xb2\xdb");                                               
  444.       if (parts > 1)
  445.         sprintf (line2, " stop_7+. (%s/%02X) [%lX]", filename, parts, ftimestamp);
  446.       else
  447.         sprintf (line2, " stop_7+. (%s) [%lX]", filename, ftimestamp);
  448.       memcpy (line, line2, strlen(line2));
  449.       mcrc (line, 1);
  450.       add_crc2 (line);
  451.       fprintf (out, "%s%s", line, delimit);
  452.       top_bottom (out, stop_buf, hdrname, part, parts);
  453.       if (endstr)
  454.         fprintf (out, "%s%s", endstr, delimit);
  455.  
  456.       /* OK. This part is done. */
  457.       fclose (out);
  458.     }
  459.     else
  460.       if (ftstamp0 && ftstamp0 != ftimestamp)
  461.         printf ("\007Warning: Timestamp in error report differs from the original file!\n");
  462.  
  463.     if (ferror(out)) /* did any errors occur while writing? */
  464.     {
  465.       printf ("\n\007Write error. Break.\n");
  466.       fclose (in);
  467.       return (1);
  468.     }
  469.  
  470.     if (_part || correct)
  471.       part = 256;
  472.   } /* end of for() */
  473.  
  474.   /* all parts done.
  475.      tell user about action. */
  476.   if (!correct)
  477.   {
  478.     printf ("\n\nEncoding successful!\n");
  479.     if (fls)
  480.     {
  481.       if (!(out = fopen ("7plus.fls", OPEN_WRITE_TEXT)))
  482.         return (14);
  483.       fnsplit (filename, NULL, NULL, _file, NULL);
  484.       fprintf (out, "%d %s\n", parts, _file);
  485.       fclose (out);
  486.     }
  487.   }
  488.   fclose (in);
  489.   return (0);
  490. }
  491.  
  492. /*
  493. *** Get info from header ifile
  494. ***
  495. ***
  496.  */
  497.  
  498. int read_tb (char *name, char *go_top, char *go_bottom)
  499. {
  500.   FILE *rfile;
  501.   int i, j, prev;
  502.   char *p, *q, line [81], compare[10];
  503.  
  504.   i = j = prev = 0;
  505.   q = NULL;
  506.  
  507.   if (!(rfile = fopen (name, OPEN_READ_TEXT)))
  508.   {
  509.     printf (cant, name);
  510.     return (2);
  511.   }
  512.  
  513.   q = go_top;
  514.   strcpy (compare, "@@TOP\n");
  515.  
  516.   while (1 == 1)
  517.   {
  518.     p = my_fgets (line, 80, rfile);
  519.  
  520.     if (strnicmp (p, compare, strlen(compare)))
  521.     {
  522.       *q = EOS;
  523.       j  = EOF;
  524.     }
  525.     else
  526.     {
  527.       i = 0;
  528.       do
  529.       {
  530.         prev = j;
  531.  
  532.         q[i] = j = fgetc(rfile);
  533.  
  534.         if (j == '\r')
  535.           continue;
  536.         i++;
  537.       }
  538.       while (j != EOF && !(j == '@' && prev == '\n') && i < 256);
  539.  
  540.       q[i-2] = '\n';
  541.       q[i-1] = EOS;
  542.     }
  543.  
  544.     if (j != '@' && j != EOF)
  545.       do
  546.       {
  547.         prev = j;
  548.         j = fgetc(rfile);
  549.       }
  550.       while (j != EOF && !(j == '@' && prev == '\n'));
  551.  
  552.     if (j == '@')
  553.       ungetc (j, rfile);
  554.  
  555.     if (j == EOF && q == go_bottom)
  556.       break;
  557.  
  558.     if (q == go_top)
  559.     {
  560.       q = go_bottom;
  561.       strcpy (compare, "@@BOTTOM\n");
  562.     }
  563.   }
  564.   fclose (rfile);
  565.  
  566.   return (0);
  567. }
  568.  
  569. /*
  570. *** output head or foot
  571. ***
  572. ***
  573.  */
  574.  
  575. int top_bottom (FILE *wfile, char *top_bot, char *orgname, int part, int parts)
  576. {
  577.   int i;
  578.   char __file[9], __ext[5];
  579.  
  580.   fnsplit (orgname, NULL, NULL, _file, _ext);
  581.   strcpy (__file, _file);
  582.   strcpy (__ext , _ext );
  583.   strlwr (_file);
  584.   strlwr (_ext );
  585.  
  586.   i = 0;
  587.   while (top_bot[i] != EOS)
  588.   {
  589.     if (top_bot[i] == '%')
  590.     {
  591.       i++;
  592.       if (!top_bot[i])
  593.         break;
  594.  
  595.       switch (top_bot[i])
  596.       {
  597.         case 'o': fprintf (wfile, "%s%s", _file, _ext);
  598.                   break;
  599.         case 'O': fprintf (wfile, "%s%s", __file, __ext);
  600.                   break;
  601.         case 'n': fprintf (wfile, "%s.p%02x", _file, part);
  602.                   break;
  603.         case 'N': fprintf (wfile, "%s.P%02X", __file, part);
  604.                   break;
  605.         case 'p': fprintf (wfile, "%d", part);
  606.                   break;
  607.         case 'P': fprintf (wfile, "%02X", part);
  608.                   break;
  609.         case 'q': fprintf (wfile, "%d", parts);
  610.                   break;
  611.         case 'Q': fprintf (wfile, "%02X", parts);
  612.                   break;
  613.         case '%': fprintf (wfile, "%s", "%");
  614.                   break;
  615.  
  616.         default : fprintf (wfile, "%%%c", top_bot[i]);
  617.       }
  618.       i++;
  619.     }
  620.     if (!top_bot[i])
  621.       break;
  622.  
  623.     if (top_bot[i] == '\n')
  624.       fprintf (wfile, "%s", delimit);
  625.     else
  626.       my_putc (top_bot[i], wfile);
  627.  
  628.     i++;
  629.   }
  630.  
  631.   return (0);
  632. }
  633.